home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / AVIStripeSystem.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-20  |  7.0 KB  |  286 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Copyright (C) 1998-2001 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include "VirtualDub.h"
  19.  
  20. #include <string.h>
  21. #include <stdio.h>
  22. #include <ctype.h>
  23.  
  24. #include <windows.h>
  25. #include <vfw.h>
  26.  
  27. #include "ProgressDialog.h"
  28. #include "Error.h"
  29.  
  30. #include "AVIStripeSystem.h"
  31.  
  32. ///////////////////////////////////////////////////////////////////////////
  33. //
  34. //    AVIStripe
  35. //
  36. ///////////////////////////////////////////////////////////////////////////
  37.  
  38. void *AVIStripe::operator new(size_t stSize, int iNameBytes) {
  39.     return malloc(stSize + iNameBytes);
  40. }
  41.  
  42. ///////////////////////////////////////////////////////////////////////////
  43. //
  44. //    AVIStripeSystem
  45. //
  46. ///////////////////////////////////////////////////////////////////////////
  47.  
  48. void AVIStripeSystem::_construct(int nStripes) {
  49.     int i;
  50.  
  51.     this->nStripes = nStripes;
  52.  
  53.     if (!(stripe = new AVIStripe *[nStripes]))
  54.         throw MyMemoryError();
  55.  
  56.     for(i=0; i<nStripes; i++)
  57.         stripe[i] = NULL;
  58. }
  59.  
  60. AVIStripeSystem::AVIStripeSystem(int nStripes) {
  61.     _construct(nStripes);
  62. }
  63.  
  64. static bool get_line(char *buf, size_t buf_size, FILE *f) {
  65.     char *s;
  66.  
  67.     do {
  68.         if (!fgets(buf, buf_size, f))
  69.             return false;
  70.  
  71.         s = buf;
  72.  
  73.         while(*s && isspace(*s) && *s!='\n')
  74.             ++s;
  75.  
  76.     } while(!*s || *s=='\n' || buf[0]=='#');
  77.  
  78.     return true;
  79. }
  80.  
  81. AVIStripeSystem::AVIStripeSystem(char *szFile) {
  82.     FILE *f = NULL;
  83.  
  84.     stripe = NULL;
  85.  
  86.     try {
  87.         char linebuf[512];
  88.         int stripe_cnt, cur;
  89.         int lineno = 2;
  90.         char *s, *t;
  91.  
  92.         // Type of lines we are trying to parse:
  93.         //
  94.         //    0   i   131072     65536      e:\capture_master.avi
  95.         //    0   v   4194304    1048576   "e:\capture video stripe 1.avi"
  96.         //  -1  v    1048576    524288    "i:\capture video stripe 2.avi"
  97.  
  98.  
  99.         f = fopen(szFile, "r");
  100.         if (!f) throw MyError("Couldn't open stripe definition file \"%s\"", szFile);
  101.  
  102.         if (!get_line(linebuf, sizeof linebuf, f))
  103.                 throw MyError("Failure reading first line of stripe def file");
  104.  
  105.         if (1!=sscanf(linebuf, " %d \n", &stripe_cnt))
  106.             throw MyError("First line of stripe definition file must contain stripe count");
  107.  
  108.         if (stripe_cnt<=0)
  109.             throw MyError("Invalid number of stripes (%d)", stripe_cnt);
  110.  
  111.         _construct(stripe_cnt);
  112.  
  113.         for(cur=0; cur<stripe_cnt; cur++) {
  114.             int iPri, iName;
  115.             long lBuffer, lChunk;
  116.             char cMode[2];
  117.             int match_count;
  118.  
  119.             if (!get_line(linebuf, sizeof linebuf, f))
  120.                 throw MyError("Failure reading stripe definition file");
  121.  
  122.             match_count = sscanf(linebuf, " %d %1s %ld %ld %n", &iPri, cMode, &lBuffer, &lChunk, &iName);
  123.  
  124.             if (match_count != 4)
  125.                 throw MyError("Stripe definition parse error: line %d", lineno);
  126.  
  127.             t = s = linebuf + iName;
  128.             if (*s=='"') {
  129.                 ++s, ++t;
  130.                 while(*t && *t!='\n' && *t!='"') ++t;
  131.             } else
  132.                 while(*t && *t!='\n' && !isspace(*t)) ++t;
  133.  
  134.             if (t<=s)
  135.                 throw MyError("Stripe definition parse error: line %d -- no stripe filename!", lineno);
  136.  
  137.             switch(tolower(cMode[0])) {
  138.             case 'm':    cMode[0] = AVIStripe::MODE_MASTER; break;
  139.             case 'i':    cMode[0] = AVIStripe::MODE_INDEX; break;
  140.             case 'v':    cMode[0] = AVIStripe::MODE_VIDEO; break;
  141.             case 'a':    cMode[0] = AVIStripe::MODE_AUDIO; break;
  142.             case 'b':    cMode[0] = AVIStripe::MODE_BOTH; break;
  143.             default:
  144.                 throw MyError("Invalid stripe mode '%c'", cMode[0]);
  145.             };
  146.  
  147.             // Allocate a stripe structure and copy the data into it
  148.  
  149.             if (!(stripe[cur] = new(t+1-s) AVIStripe))
  150.                 throw MyMemoryError();
  151.  
  152.             *t=0;
  153.  
  154.             stripe[cur]->lBufferSize = lBuffer;
  155.             stripe[cur]->lChunkSize    = lChunk;
  156.             stripe[cur]->iNameLen    = t+1-s;
  157.             stripe[cur]->cStripeMode    = cMode[0];
  158.             stripe[cur]->scPriority    = iPri;
  159.             strcpy(stripe[cur]->szName, s);
  160.  
  161.             ++lineno;
  162.         }
  163.     } catch(...) {
  164.         if (f) fclose(f);
  165.         _destruct();
  166.         throw;
  167.     }
  168.     fclose(f);
  169. }
  170.  
  171. void AVIStripeSystem::_destruct() {
  172.     int i;
  173.  
  174.     if (stripe)
  175.         for(i=0; i<nStripes; i++)
  176.             delete stripe[i];
  177.  
  178.     delete stripe;
  179. }
  180.  
  181. AVIStripeSystem::~AVIStripeSystem() {
  182.     _destruct();
  183. }
  184.  
  185.  
  186. int AVIStripeSystem::getStripeCount() {
  187.     return nStripes;
  188. }
  189.  
  190. AVIStripe *AVIStripeSystem::getStripeInfo(int nStripe) {
  191.     return stripe[nStripe];
  192. }
  193.  
  194.  
  195. ///////////////////////////////////////////////////////////////////////////
  196. //
  197. //    AVIStripeIndexLookup
  198. //
  199. ///////////////////////////////////////////////////////////////////////////
  200.  
  201. AVIStripeIndexLookup::AVIStripeIndexLookup(IAVIReadStream *pasIndex) {
  202.     index_table        = NULL;
  203.  
  204.     try {
  205.         AVIStripeIndexEntry *asieptr;
  206.         LONG lStart, lCur, lEnd;
  207.  
  208.         if (-1 == (lStart = pasIndex->Start())
  209.             || -1 == (lEnd = pasIndex->End()))
  210.  
  211.             throw MyError("Stripe index: can't get start/end of index stream");
  212.  
  213.         ProgressDialog pd(NULL, "AVI Striped Import Filter", "Reading stripe index", lEnd-lStart, true);
  214.  
  215.         pd.setValueFormat("Frame %ld/%ld");
  216.  
  217.         index_table_size = lEnd - lStart;
  218.  
  219.         if (!(index_table = new AVIStripeIndexEntry[index_table_size]))
  220.             throw MyMemoryError();
  221.  
  222.         asieptr = index_table;
  223.  
  224.         pasIndex->BeginStreaming(lStart, lEnd, 100000);
  225.  
  226.         lCur = lStart;
  227.  
  228.         while(lCur < lEnd) {
  229.             HRESULT err;
  230.             LONG lActualBytes, lActualSamples;
  231.  
  232.             err = pasIndex->Read(lCur, lEnd-lCur, asieptr, sizeof(AVIStripeIndexEntry)*(lEnd-lCur), &lActualBytes, &lActualSamples);
  233.  
  234.             if (err == AVIERR_OK && !lActualSamples)
  235.                 err = AVIERR_FILEREAD;
  236.  
  237.             if (err != AVIERR_OK) throw MyAVIError("AVIStripeIndex",err);
  238.  
  239.             if (lActualBytes != lActualSamples * sizeof(AVIStripeIndexEntry))
  240.                 throw MyError("Stripe index: bad index marks! (not 16 bytes)");
  241.  
  242.             lCur += lActualSamples;
  243.             asieptr += lActualSamples;
  244.  
  245.             pd.advance(lCur);
  246.             pd.check();
  247.         }
  248.  
  249.         pasIndex->EndStreaming();
  250.  
  251.     } catch(...) {
  252.         delete index_table;
  253.         throw;
  254.     }
  255. }
  256.  
  257. AVIStripeIndexLookup::~AVIStripeIndexLookup() {
  258.     delete index_table;
  259. }
  260.  
  261. AVIStripeIndexEntry *AVIStripeIndexLookup::lookup(long sample) {
  262.     long l, pivot, r;
  263.  
  264. //    _RPT1(0, "AVIStripeIndexEntry: looking up %ld\n", sample);
  265.  
  266.     l = 0;
  267.     r = index_table_size-1;
  268.  
  269.     while(l <= r) {
  270.         pivot = (l+r)/2;
  271.  
  272.         if (sample > index_table[pivot])
  273.             l = pivot+1;
  274.         else if (sample < index_table[pivot])
  275.             r = pivot-1;
  276.         else {
  277. //            _RPT2(0,"\tFound in stripe %ld at %ld\n", index_table[pivot].lStripe+1, index_table[pivot].lStripeSample);
  278.             return &index_table[pivot];
  279.         }
  280.     }
  281.  
  282.     _RPT0(0,"\tNot found!\n");
  283.  
  284.     return NULL;
  285. }
  286.